#include <TGS/MapControl2.0/MapToPixel.h>
#include <TGS/GeoMath2.0/Point.h>
#include <TGS/GeoMath2.0/Polygon.h>
#include <TGS/GeoMath2.0/Envelope.h>
#include <cassert>
#include <QPolygon>
#include <QPolygonF>
#include <QPointF>

namespace TGS{
namespace MapControl{


MapToPixel::MapToPixel()
{
}

MapToPixel::~MapToPixel()
{
}

MapToPixel::Point MapToPixel::screenToMap(const QPoint& screenPoint ) const
{
	return screenToMap( screenPoint.x(), screenPoint.y() );
}

MapToPixel::Point MapToPixel::screenToMap( int screenX, int screenY ) const
{
	double x = screenX * _MapUnitsPerPixel + _mapMinX;
	double y = -1 * (( screenY - _screenMaxY ) * _MapUnitsPerPixel - _mapMinY );
	return Point( x, y );
}

MapToPixel::Polygon MapToPixel::screenToMap(const QPolygon& screenPolygon ) const
{
	Polygon result;
	for (int i = 0; i < screenPolygon.size(); ++i)
	{
		Point mapPoint = screenToMap(screenPolygon[i]);
		result.appendPoint(mapPoint.getX(), mapPoint.getY());
	}

	return result;
}



void MapToPixel::setMapUnitsPerPixel( double mapUnitsPerPixel )
{
	_MapUnitsPerPixel = mapUnitsPerPixel;
}

double MapToPixel::mapUnitsPerPixel() const
{
	return _MapUnitsPerPixel;
}

void MapToPixel::setParameters(double mapUnitsPerPixel, double mapMinX, double mapMinY, double screenMaxY )
{
	_MapUnitsPerPixel = mapUnitsPerPixel;
	_mapMinX = mapMinX;
	_mapMinY = mapMinY;
	_screenMaxY = screenMaxY;

}

QPoint MapToPixel::mapToScreen( double mapPointX, double mapPointY ) const
{
	int screenX = ( mapPointX - _mapMinX ) / _MapUnitsPerPixel;
	int screenY = _screenMaxY - ( mapPointY - _mapMinY ) / _MapUnitsPerPixel;

	return QPoint(screenX, screenY);
}

QPoint MapToPixel::mapToScreen( const Point& mapPoint ) const
{
	return mapToScreen(mapPoint.getX(), mapPoint.getY());
}

QPolygon MapToPixel::mapToScreen( const QPolygonF& mapPolygon ) const
{
	QPolygon result;
	for (int i = 0; i < mapPolygon.size(); ++i)
	{
		result.push_back(mapToScreen(mapPolygon[i]));
	}

	return result;
}

QPoint MapToPixel::mapToScreen( const QPointF& mapPoint ) const
{
	return mapToScreen(mapPoint.x(), mapPoint.y());
}

QPolygon MapToPixel::mapToScreen( const Polygon& mapPolygon ) const
{
	QPolygon result;
	for (size_t i = 0; i < mapPolygon.getPointCount(); ++i)
	{
		result.push_back(mapToScreen(mapPolygon[i]));
	}

	return result;
}

QRect MapToPixel::mapToScreen( const Envelope& envelope ) const
{
	Polygon polygon;
	polygon.appendPoint(envelope.getMinX(), envelope.getMinY());
	polygon.appendPoint(envelope.getMaxX(), envelope.getMinY());
	polygon.appendPoint(envelope.getMaxX(), envelope.getMaxY());
	polygon.appendPoint(envelope.getMinX(), envelope.getMaxY());

	return mapToScreen(polygon).boundingRect();

}

TGS::GeoMath::Envelope MapToPixel::screenToMap( const QRect& rect ) const
{
	QPolygon polgon;
	polgon.append(QPoint(rect.left(), rect.top()));
	polgon.append(QPoint(rect.right(), rect.top()));
	polgon.append(QPoint(rect.right(), rect.bottom()));
	polgon.append(QPoint(rect.left(), rect.bottom()));

	return screenToMap(polgon).getEnvelope();
}

}//MapControl
}//TGS
